//给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
//
// 注意：不要求字典中出现的单词全部都使用，并且字典中的单词可以重复使用。
//
//
//
// 示例 1：
//
//
//输入: s = "leetcode", wordDict = ["leet", "code"]
//输出: true
//解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
//
//
// 示例 2：
//
//
//输入: s = "applepenapple", wordDict = ["apple", "pen"]
//输出: true
//解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
//注意，你可以重复使用字典中的单词。
//
//
// 示例 3：
//
//
//输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
//输出: false
//
//
//
//
// 提示：
//
//
// 1 <= s.length <= 300
// 1 <= wordDict.length <= 1000
// 1 <= wordDict[i].length <= 20
// s 和 wordDict[i] 仅有小写英文字母组成
// wordDict 中的所有字符串 互不相同
//
//
// Related Topics 字典树 记忆化搜索 数组与矩阵 哈希表 字符串 动态规划 👍 2125 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
function wordBreak(s: string, wordDict: string[]): boolean {

    /*?
        ? dp[i]表示字符串长度为i的话，dp[i]为true，表示可以拆分为一个或多个在字典中出现的单词。
    ?*/
    const dp : boolean[] = new Array(s.length + 1).fill(false)
    dp[0] = true;
    for (let j = 1; j <= s.length; j ++) {
        for (let i = 0; i < j; i ++) {
            //? dp[i] === true表示前面的所有字符串均已经匹配上了 否则就表示中间差了一截或者重复使用某些字符 则为false
            //? 这段也能很好的解决catsand 能匹配cats和sand的问题
            if (wordDict.includes(s.slice(i, j)) && dp[i] === true) {
                dp[j] = true
                break
            }
        }
    }
    return dp[dp.length - 1]
};
//leetcode submit region end(Prohibit modification and deletion)
